﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyTime.Core.Entities
{
    public interface ITimeTracker
    {
        void ReportTime(string task, DateTime time);
        void ReportTime(string task, DateTime time, DateTime endTime);

        /// <summary>
        /// Gets or sets the interval (in minutes) fo how often the timetracker should pop up its window
        /// </summary>
        double Interval { get; set; }

        /// <summary>
        /// Gets or set if the application should start with windows
        /// </summary>
        bool AutoStart { get; set; }

        System.Collections.Specialized.NameValueCollection Settings { get; }

        /// <summary>
        /// Event i striggered after the given pop up interval
        /// </summary>
        event EventHandler TimeToReport;

        /// <summary>
        /// Event is triggered after TimeToReport event is fired and nothing has happened for 5 minutes
        /// </summary>
        event EventHandler TimeOut;

        List<ProviderFactory.Entities.ITimeItem> GetAllTimeItems();
        void StopTimer();
        void StartTimer();
    }

    public class TimeTracker : ITimeTracker
    {
        private const string appName = "MyTime Timetracking";
        private string _runningAssemblyName;
        private object _lock = new object();
        private System.Timers.Timer _timer; // = new System.Timers.Timer();
        private System.Timers.Timer _timeOutTimer; // = new System.Timers.Timer();
        public TimeTracker(string runningAssemblyName)
        {
            _runningAssemblyName = runningAssemblyName;
            SetupTimer();
        }
        public void ReportTime(string task, DateTime time)
        {
            var msg = string.Format("{0};{1}{2}", time, task.Replace(";", ""), Environment.NewLine);
            MyTime.ProviderFactory.Instance.Current.AddTask(new DefaultTimeItem(task, time));
        }
        public void ReportTime(string task, DateTime time, DateTime endTime)
        {
            var msg = string.Format("{0};{1}{2}", time, task.Replace(";", ""), Environment.NewLine);
            MyTime.ProviderFactory.Instance.Current.AddTask(new DefaultTimeItem(task, time, endTime));
        }
        /// <summary>
        /// Gets or sets the interval (in minutes) fo how often the timetracker should pop up its window
        /// </summary>
        public double Interval
        {
            get
            {
                double res = 60;
                if (double.TryParse(ConfigHelper.Get("Interval"), out res))
                    return res;
                return 60;
            }
            set
            {
                ConfigHelper.Set("Interval", value.ToString());
                SetupTimer();
            }
        }
        /// <summary>
        /// Gets or set if the application should start with windows
        /// </summary>
        public bool AutoStart
        {
            get
            {
                string value = WindowsHelper.GetRegistryValue<string>(appName);
                if (value == null)
                    return false;
                return (value == _runningAssemblyName);
            }
            set
            {
                if (value)
                    WindowsHelper.SetRegistry(appName, _runningAssemblyName);
                else
                    WindowsHelper.UnSetRegistry(appName);
            }
        }

        /// <summary>
        /// Event i striggered after the given pop up interval
        /// </summary>
        public event EventHandler TimeToReport;
        /// <summary>
        /// Event is triggered after TimeToReport event is fired and nothing has happened for 5 minutes
        /// </summary>
        public event EventHandler TimeOut;

        public List<ProviderFactory.Entities.ITimeItem> GetAllTimeItems()
        {
            return ProviderFactory.Instance.Current.GetAllTime().ToList();
        }
        public System.Collections.Specialized.NameValueCollection Settings
        {
            get
            {
                return ProviderFactory.Instance.Current.Settings;
            }
        }
        public void StopTimer()
        {
            _timer.Enabled = false;
            _timer.Stop();
        }
        public void StartTimer()
        {
            _timer.Enabled = true;
            _timer.Start();
        }
        private void SetupTimer()
        {
            lock (_lock)
            {
                if (_timer == null)
                    _timer = new System.Timers.Timer();
                if (_timeOutTimer == null)
                    _timeOutTimer = new System.Timers.Timer();
                _timeOutTimer.Interval = TimeSpan.FromMinutes(this.Interval / 10).TotalMilliseconds;
                _timer.Interval = TimeSpan.FromMinutes(this.Interval).TotalMilliseconds;// this.Interval * 60000;
                StartTimer();
                _timer.Elapsed += _timer_Elapsed;
                _timeOutTimer.Elapsed += _timeOutTimer_Elapsed;
            }
        }

        void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (TimeToReport != null)
                TimeToReport(sender, e);
            //_timeOutTimer.Elapsed += _timeOutTimer_Elapsed;
            _timeOutTimer.AutoReset = false;
            _timeOutTimer.Start();
        }

        void _timeOutTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (TimeOut != null)
                TimeOut(sender, e);
            //_timeOutTimer.Elapsed -= _timeOutTimer_Elapsed;
            _timeOutTimer.Stop();
            //_timeOutTimer.Dispose();
        }
    }
}
